package com.hemerasolutions.v2trainer.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ComponentSystemEvent;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.hemerasolutions.v2trainer.controller.interfaces.UserBeanInterface;
import com.hemerasolutions.v2trainer.model.equipment.VersionableEquipment;
import com.hemerasolutions.v2trainer.model.exercise.Equipment;
import com.hemerasolutions.v2trainer.model.exerciseGroup.ExerciseGroup;
import com.hemerasolutions.v2trainer.model.exerciseGroup.VersionableExerciseGroup;
import com.hemerasolutions.v2trainer.model.interfaces.AgreementHolderInterface;
import com.hemerasolutions.v2trainer.model.library.Library;
import com.hemerasolutions.v2trainer.model.modality.Modality;
import com.hemerasolutions.v2trainer.model.modality.VersionableModality;
import com.hemerasolutions.v2trainer.model.training.Training;
import com.hemerasolutions.v2trainer.model.training.VersionableTraining;
import com.hemerasolutions.v2trainer.model.users.Academy;
import com.hemerasolutions.v2trainer.model.users.Athlete;
import com.hemerasolutions.v2trainer.model.users.PersonalTrainer;
import com.hemerasolutions.v2trainer.model.users.Teacher;
import com.hemerasolutions.v2trainer.model.users.User;
import com.hemerasolutions.v2trainer.service.ExceptionService;
import com.hemerasolutions.v2trainer.service.interfaces.MailServiceInterface;
import com.hemerasolutions.v2trainer.service.interfaces.UserServiceInterface;

@Controller
@ManagedBean(name="userBean")
@Scope("session")
public class UserBean extends BaseBean implements UserBeanInterface {

	private static final long serialVersionUID = 1L;

	@Autowired
	private UserServiceInterface userService;

	@Autowired
	private MailServiceInterface mailService;

	private TreeNode libraryRoot;
	
	private User user;

	private String userName;
	
	private String password;
	
	private String response;
	
	private String forgottenUser;

	private AgreementHolderInterface agreementHolder;

	private List<AgreementHolderInterface> agreementHolders;

	
	
	public UserBean() {
		super();
		this.user = new User();
	}

	@PostConstruct
	public void init(){
		this.loadLibrary();
		this.loadHolders();
	}
	
	public void loadHolders(ComponentSystemEvent evt)throws AbortProcessingException{ 
		this.loadHolders();
	}

	private void loadHolders() {
		this.agreementHolder = null;
		this.agreementHolders = new ArrayList<AgreementHolderInterface>();		

		if(this.getActiveUserType() == User.USERTYPE_ATHLETE){
			this.agreementHolders.addAll(this.getActiveActor(Athlete.class).getAcademys());
			this.agreementHolders.addAll(this.getActiveActor(Athlete.class).getPersonalTrainers());
			if(this.agreementHolders.size() >= 1){
				this.agreementHolder = this.agreementHolders.get(0);
			}
		
		}else if(this.getActiveUserType() == User.USERTYPE_TEACHER){
			this.agreementHolder = this.getActiveActor(Teacher.class).getAcademy();
			this.agreementHolders.add(this.getActiveActor(Teacher.class).getAcademy());
		}else if(this.getActiveUserType() == User.USERTYPE_ACADEMY){
			this.agreementHolder = this.getActiveActor(Academy.class);
		}else if(this.getActiveUserType() == User.USERTYPE_PT){
			this.agreementHolder = this.getActiveActor(PersonalTrainer.class);
		}
	}

	private void loadLibrary() {

		libraryRoot = new DefaultTreeNode("Root", null);  
        TreeNode librarys = new DefaultTreeNode(this.localizedText("Librarys"), libraryRoot);
        
		for(Library library:this.user.getLibrarys()){

			TreeNode libraryNode = new DefaultTreeNode(library.getName(), librarys);

			DefaultTreeNode modalitysNode 		= new DefaultTreeNode(this.localizedText("modalitys"), libraryNode);  
			DefaultTreeNode trainingSystemsNode = new DefaultTreeNode(this.localizedText("TrainingSystems"), libraryNode);  
			DefaultTreeNode exerciseGroupsNode	= new DefaultTreeNode(this.localizedText("ExerciseGroups"), libraryNode);  
			DefaultTreeNode trainingsNode 		= new DefaultTreeNode(this.localizedText("Trainings"), libraryNode);  
			DefaultTreeNode equipmentsNode 		= new DefaultTreeNode(this.localizedText("Equipments"), libraryNode);  
			
			for(VersionableModality vm:library.getVersionableModalitys()){
				for(Modality modality:vm.getModalityVersions()){
					new DefaultTreeNode(modality.getName(),modality,modalitysNode);
				}
			}

			for(VersionableExerciseGroup veg:library.getVersionableExerciseGroups()){
				for(ExerciseGroup eg:veg.getExerciseGroupVersions()){
					new DefaultTreeNode(eg.getName(),eg,exerciseGroupsNode);
				}
				
			}
			
			for(VersionableTraining vt: library.getVersionableTrainings()){
				for(Training training:vt.getTrainingVersions()){
					if(training.isTrainingSystem()){
						new DefaultTreeNode(training.getName(),training,trainingSystemsNode);
					}else{
						new DefaultTreeNode(training.getName(),training,trainingsNode);
					}
				}
			}
			
			for(VersionableEquipment ve:library.getVersionableEquipments()){
				for(Equipment equipment:ve.getEquipmentVersions()){
					new DefaultTreeNode(equipment.getName(),equipment,equipmentsNode);
				}
			}
		}
		
        librarys.setExpanded(true);
	}

	public void init(ComponentSystemEvent ev){
	    if (response != null) { 
	    	this.showErrorMessage(	this.localizedText("Error"), 
	    							this.localizedText(response));
	    }
	}
	
	// Chamado ao logar
	@Override
	public String login() throws IOException, ServletException{

		ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        
        RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/j_spring_security_check");
 
        dispatcher.forward((ServletRequest) context.getRequest(),(ServletResponse) context.getResponse());
 
        FacesContext.getCurrentInstance().responseComplete();

        return null;
    }

	@Override
	public String goForgetPassword() throws IOException,ServletException{

		return "forgotpassword.jsf";

	}

	@Override
	public void sendPassword(ActionEvent ev){
		
		try{
			mailService.sendPassword(userService.getUserByUserEmail(this.forgottenUser));
			this.showInfoMessage(this.localizedText("Success"),this.localizedText("EmailSent"));

		}catch (ExceptionService e) {
	    	this.showErrorMessage(	this.localizedText("ErrorSendingEmail"), 
					this.localizedText("ContactTheAdministrator"));
		}
		
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getForgottenUser() {
		return forgottenUser;
	}

	public void setForgottenUser(String forgottenUser) {
		this.forgottenUser = forgottenUser;
	}


	public String getResponse() {
		return response;
	}

	public void setResponse(String response) {
		this.response = response;
	}

	public TreeNode getLibraryRoot() {
		return libraryRoot;
	}

	public void setLibraryRoot(TreeNode libraryRoot) {
		this.libraryRoot = libraryRoot;
	}

	public String getUserName() {
		return userName;
	}

	public String getPassword() {
		return password;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setAgreementHolder(AgreementHolderInterface ah){
		this.agreementHolder = ah;
	}

	public AgreementHolderInterface getAgreementHolder(){
		return this.agreementHolder;
	}
	
	
}
